using System;
using System.Collections;
using System.Reflection;
using cuberga.Workflow;

namespace cuberga.GA
{
    class GACoreFactory: ICoreFactory
    {
        private Hashtable _registeredClasses = new Hashtable();
        
        public GACoreFactory() {
            RegisterExecutableTypes();
        }

        public ICoreProcess CreateCoreProcess(string className, object[] constructorParameters)
        {
            return CreateGAProcess(className, constructorParameters);
            //throw new NotImplementedException();
        }


        private void RegisterExecutableTypes()
        {
            Assembly assembly = Assembly.GetExecutingAssembly();

            foreach (Type type in assembly.GetTypes())
            {
                if (!type.IsAbstract &&
                    !type.IsNestedPrivate && // Check for MockObjects
                    type.Namespace.StartsWith("cuberga.GA"))
                {
                    Register(type);
                }
            }
        }

        
        public void Register(Type newClass) {
            _registeredClasses.Add(newClass.Name, newClass);  
        }

        public ICoreProcess CreateGAProcess(string className) {
            return CreateGAProcess(className, null);
        }

        public ICoreProcess CreateGAProcess(string className, object[] constructorParameters) {
            return (ICoreProcess)CreateAbstractObject(className, constructorParameters);
        }
        
        //public AbstractBooleanCondition CreateCondition(string className) {
        //    return (AbstractBooleanCondition)CreateAbstractObject(className, null);
        //}
        
        private Object CreateAbstractObject(string className, object[] constructorParameters) {
            if (!_registeredClasses.Contains(className)) { 
                throw new Exception();
            }

            Type objType = (Type)_registeredClasses[className];
            
            return Activator.CreateInstance( objType, constructorParameters );
        }

    }
}
